package com.nowadays.mobile.ui;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.Vibrator;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.nowadays.mobile.R;
import com.nowadays.mobile.adapter.FocusListAdapter;
import com.nowadays.mobile.model.FocusDayList;
import com.nowadays.mobile.mvp.presenter.MainPresenter;
import com.nowadays.mobile.mvp.presenter.MainPresenterImpl;
import com.nowadays.mobile.mvp.view.MainView;
import com.nowadays.mobile.service.NotificationService;
import com.nowadays.mobile.utils.ConstsDefine;
import com.nowadays.mobile.utils.FocusUtils;
import com.nowadays.mobile.utils.ForegroundChangeHelper;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;

import java.lang.ref.WeakReference;
import java.util.List;

import cn.iwgang.countdownview.CountdownView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, CountdownView.OnCountdownEndListener, MainView, CountdownView.OnCountdownIntervalListener, ForegroundChangeHelper.OnAppForegroundChangeListener {
  private CountdownView leftTime;
  private SlidingUpPanelLayout slidingUpPanelLayout;
  private RelativeLayout mainContent;

  private Button focusBtn;

  private RecyclerView recyclerView;
  private FocusListAdapter focusListAdapter;
  private static final String Tag = MainActivity.class.getSimpleName();

  private MainPresenter presenter;

  private static NotificationService service;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    Log.i(Tag, this.getClass().getSimpleName() + " onCreate");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    presenter = new MainPresenterImpl(this);
    presenter.initVoice();

    ForegroundChangeHelper.getInstance().add2ForegroundChangeListenerList(new WeakReference<ForegroundChangeHelper.OnAppForegroundChangeListener>(this));
    initToolbar();
    leftTime = (CountdownView) findViewById(R.id.left_time);
    leftTime.setOnCountdownEndListener(this);
    leftTime.setOnCountdownIntervalListener(FocusUtils.MILLIS_IN_SECOND, this);
//    TextView colon = (TextView) findViewById(R.id.colon);
//    setTextWithCustomFont(leftTime, colon);

    focusBtn = (Button) findViewById(R.id.focus_btn);
    slidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
    mainContent = (RelativeLayout) findViewById(R.id.main_content);

    focusBtn.setOnClickListener(this);

    //1.focusTimer是minutes,取出时已转成seconds
    //2.直接显示
    //init focus list
    recyclerView = (RecyclerView) findViewById(R.id.focus_list);
    focusListAdapter = new FocusListAdapter(this);

    LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
    mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    recyclerView.setLayoutManager(mLayoutManager);

    recyclerView.setAdapter(focusListAdapter);
  }

  private void initToolbar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    if (toolbar != null) {
      setSupportActionBar(toolbar);

      getSupportActionBar().setDisplayShowTitleEnabled(false);
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.action_settings:
        Intent intent = new Intent(MainActivity.this, SettingActivity.class);
        startActivity(intent);
        break;
      default:
        break;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override
  public void updateFocusListData(List<FocusDayList> data) {
    focusListAdapter.setData(data);
  }

  @Override
  public void onBackPressed() {
    if (slidingUpPanelLayout != null &&
        (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED || slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.ANCHORED)) {
      recyclerView.scrollToPosition(0);
      slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
    } else {
      moveTaskToBack(true);
    }
  }

  @Override
  public void initShowTime(int timeSeconds) {
    leftTime.updateShow(timeSeconds * FocusUtils.MILLIS_IN_SECOND);
  }


  @Override
  public void onClick(View v) {
    switch (v.getId()) {
      case R.id.focus_btn:
        presenter.resetFocusTimes();
        presenter.switchFocus();
        break;
      default:
        break;
    }
  }

  @Override
  public void cancelNotification() {
    if(service != null) {
      unbindService(connection);
      service.hideNotification();
      service =null;
    }
//    stopService(new Intent(this, NotificationService.class));
  }

  @Override
  public void resumeNotification() {
    bindService(new Intent(this, NotificationService.class), connection, BIND_AUTO_CREATE);
//    startService(new Intent(this, NotificationService.class));
  }

  private static ServiceConnection connection = new ServiceConnection() {

    @Override
    public void onServiceDisconnected(ComponentName name) {
      if(service != null) {
        service.hideNotification();
        service = null;
      }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder) {
      NotificationService.NotificationServiceBinder binder = (NotificationService.NotificationServiceBinder) iBinder;
      service = binder.getService();
      service.showNotification();
    }
  };

  @Override
  public void switchColorAndBtn(int focusState) {
    int color = 0;
    byte newState = 0;
    switch (focusState) {
      case ConstsDefine.STATE.NONE:
        focusBtn.setText(R.string.cancel_focus);
        newState = ConstsDefine.STATE.FOCUS;
        break;
      case ConstsDefine.STATE.FOCUS_END:
        color = ContextCompat.getColor(this, R.color.accent);
        focusBtn.setBackgroundResource(R.drawable.round_button_accent);
        focusBtn.setText(R.string.stop_rest);
        newState = ConstsDefine.STATE.REST;
        break;
      case ConstsDefine.STATE.FOCUS:
      case ConstsDefine.STATE.REST:
      case ConstsDefine.STATE.REST_END:
        focusBtn.setText(R.string.start_focus);
        newState = ConstsDefine.STATE.NONE;
        break;
    }
    if (color == 0) {
      color = ContextCompat.getColor(this, R.color.primary);
      focusBtn.setBackgroundResource(R.drawable.round_button_primary);
    }
    slidingUpPanelLayout.setBackgroundColor(color);
    mainContent.setBackgroundColor(color);
    presenter.updateFocusState(newState);
  }

  //振动
  @Override
  public void showVibrate() {
    Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
    long[] pattern = {100, 400, 100, 400};   // 停止 开启 停止 开启
    vibrator.vibrate(pattern, -1);           //重复两次上面的pattern 如果只想震动一次，index设为-1
  }


  @Override
  protected void onRestart() {
    super.onRestart();
    Log.i(Tag, this.getClass().getSimpleName() + " onRestart");
    presenter.onRestart();
  }


  @Override
  protected void onStart() {
    super.onStart();
    //if timer not start, init focus_time and focus list
    Log.i(Tag, this.getClass().getSimpleName() + " onStart");
    //if has save focus timer,restore it
    //if has save rest timer,restore it
    presenter.onStart();
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i(Tag, this.getClass().getSimpleName() + " onRestoreInstanceState");
  }

  @Override
  protected void onResume() {
    super.onResume();
    Log.i(Tag, this.getClass().getSimpleName() + " onResume");
    Log.d(Tag, "threadId:" + Thread.currentThread().getId() + ",isMainThread:" + (Looper.getMainLooper() == Looper.myLooper()));
    presenter.onResume();
  }


  @Override
  public void preventLockScreen(boolean isKeep) {
    if (isKeep) {
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    } else {
      getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }
  }


  @Override
  protected void onPause() {
    super.onPause();
    presenter.onPause();
    Log.i(Tag, this.getClass().getSimpleName() + " onPause");
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Log.i(Tag, this.getClass().getSimpleName() + " onSaveInstanceState");
  }

  @Override
  protected void onStop() {
    super.onStop();
    //when low memory onStop will not called,but in this state we ignore it
    //TODO start a service to show notification and continue the countdown
    //if focusTimer not stop,save it
    //if restTimer not stop,save it

//        saveFocusTimer();
//        saveRestTimer();
    Log.i(Tag, this.getClass().getSimpleName() + " onStop");
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    Log.i(Tag, this.getClass().getSimpleName() + " onDestroy");
    presenter.onDestroy();
    //onDestroy is for free resource, not for save data
    //onDestroy may not be called, when system in low memory, activity called onPause then be killed
  }


  @Override
  public void startRestOrFocus(int time) {
    leftTime.start(time * FocusUtils.MILLIS_IN_SECOND);
  }

  @Override
  public void cancelRestOrFocus() {
    leftTime.stop();
  }

  @Override
  public void onEnd(CountdownView cv) {
//    cv.stop();
   presenter.onFocusOrRestEnd();
  }

  @Override
  public void onEnd(byte state, int time) {
    if(service != null) {
      if(state == ConstsDefine.STATE.REST) {
        service.updateTime(state, FocusUtils.displayInMinutes(time));
      } else {
        service.onEnd(FocusUtils.getMinutesOfSeconds(time));
      }
    }
  }

  @Override
  public void onInterval(CountdownView cv, long remainTime) {
    byte state = presenter.getFocusState();
    if(state == ConstsDefine.STATE.FOCUS || state == ConstsDefine.STATE.REST) {
      if (service != null) {
        service.updateTime(state, FocusUtils.displayInMinutes((int) (remainTime / FocusUtils.MILLIS_IN_SECOND)));
      }
    }
  }

  @Override
  public void onForegroundToBackground() {
    presenter.resumeNotification();
  }

  @Override
  public void onBackgroundToForeground() {
    presenter.cancelNotification();
  }
}